package cc.mrbird.grid.service.impl;

import cc.mrbird.common.domain.QueryRequest;
import cc.mrbird.common.domain.Tree;
import cc.mrbird.common.exception.FileImportException;
import cc.mrbird.common.service.impl.BaseService;
import cc.mrbird.common.util.TreeUtils;
import cc.mrbird.grid.dao.GridInfoMapper;
import cc.mrbird.grid.domain.GridInfo;
import cc.mrbird.grid.service.GridInfoService;
import cc.mrbird.management.dao.ManagementInstitutionsMapper;
import cc.mrbird.management.domain.ManagementInstitutions;
import cc.mrbird.management.service.ManagementInstitutionsService;
import cc.mrbird.system.domain.Menu;
import cc.mrbird.system.domain.User;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Service("gridInfoService")
public class GridInfoServiceImpl extends BaseService<GridInfo> implements GridInfoService {
    private Logger log = LoggerFactory.getLogger(this.getClass());
    @Autowired
    private GridInfoMapper gridInfoMapper;

    @Override
    public List<GridInfo> findGridInfoList(GridInfo gridInfo, QueryRequest request) {
        try {
            Example example = new Example(GridInfo.class);
            Criteria criteria = example.createCriteria();
            if (StringUtils.isNotBlank(gridInfo.getGrid_name())) {
                criteria.andCondition("grid_name=", gridInfo.getGrid_name());
            }
            if (StringUtils.isNotBlank(gridInfo.getGrid_scope())) {
                criteria.andCondition("grid_scope=", gridInfo.getGrid_scope());
            }
            example.setOrderByClause("grid_id");
            return this.selectByExample(example);
        } catch (Exception e) {
            log.error("error", e);
            return new ArrayList<>();
        }
    }
    @Override
    public GridInfo findByName(String grid_name) {
        Example example = new Example(User.class);
        example.createCriteria().andCondition("lower(grid_name)=", grid_name.toLowerCase());
        List<GridInfo> list = this.selectByExample(example);
        return list.isEmpty() ? null : list.get(0);
    }
    @Override
    @Transactional
    public void add(GridInfo gridInfo) {
        if(gridInfo.getParent_id()==null){
            gridInfo.setParent_id(0L);
        }
        this.save(gridInfo);
    }
    @Override
    public GridInfo findById(Long id) {
        return this.selectByKey(id);
    }

    @Override
    @Transactional
    public void deleteMana(String ids) {
        List<String> list = Arrays.asList(ids.split(","));
        this.batchDelete(list, "grid_id", GridInfo.class);
    }

    @Override
    public boolean batchImport(String fileName, MultipartFile file) throws Exception {
        boolean notNull = false;
        List<GridInfo> gridInfoList = new ArrayList<GridInfo>();
        if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
            throw new FileImportException("上传文件格式不正确");
        }
        boolean isExcel2003 = false;
        if (fileName.matches("^.+\\.(?i)(xls)$")) {
            isExcel2003 = true;
        }
        InputStream is = file.getInputStream();
        Workbook wb = null;
        if (!isExcel2003) {
            wb = new HSSFWorkbook(is);
        } else {
            wb = new XSSFWorkbook(is);
        }
        Sheet sheet = wb.getSheetAt(0);
        if(sheet!=null){
            notNull = true;
        }
        GridInfo gridInfo;
        for (int r = 1; r <= sheet.getLastRowNum(); r++) {
            Row row = sheet.getRow(r);
            if (row == null){
                continue;
            }

            gridInfo = new GridInfo();

            String name = row.getCell(0).getStringCellValue();
            if(name == null || name.isEmpty()){
                throw new FileImportException("导入失败(第"+(r+1)+"行,名称未填写)");
            }
            String scope = row.getCell(1).getStringCellValue();
            if(scope==null || scope.isEmpty()){
                throw new FileImportException("导入失败(第"+(r+1)+"行,范围未填写)");
            }
            String scopeStr = row.getCell(2).getStringCellValue();
            if(scopeStr==null ||scopeStr.isEmpty()){
                throw new FileImportException("导入失败(第"+(r+1)+"行,描述未填写)");
            }
            gridInfo.setGrid_name(name);
            gridInfo.setGrid_scope(scope);
            gridInfo.setGrid_scopeStr(scopeStr);
            gridInfoList.add(gridInfo);
        }
        for (GridInfo gridResord : gridInfoList) {
            String grid_name = gridResord.getGrid_name();
            int cnt = gridInfoMapper.selectByName(grid_name);
            if (cnt == 0) {
                gridInfoMapper.addGridInfo(gridResord);
            } else {
                gridInfoMapper.updateGridInfoByName(gridResord);
            }
        }
        return notNull;
    }

    @Override
    public Tree<GridInfo> getGridTree() {
        List<Tree<GridInfo>> trees = new ArrayList<>();
        Example example = new Example(GridInfo.class);
        example.createCriteria().andCondition("type =", 0);
        example.setOrderByClause("grid_id");
        List<GridInfo> gridInfos = this.selectByExample(example);
        buildTrees(trees, gridInfos);
        return TreeUtils.build(trees);
    }

    @Override
    public List<GridInfo> findAllGrids() {
        try {
            List<GridInfo> list = gridInfoMapper.findAllGrids();
            return list;
        } catch (NumberFormatException e) {
            log.error("error", e);
            return new ArrayList<>();
        }
    }

    private void buildTrees(List<Tree<GridInfo>> trees, List<GridInfo> gridInfos) {
        gridInfos.forEach(gridInfo -> {
            Tree<GridInfo> tree = new Tree<>();
            tree.setId(gridInfo.getGrid_id().toString());
            tree.setParentId(gridInfo.getParent_id().toString());
            tree.setText(gridInfo.getGrid_name());
            trees.add(tree);
        });
    }

    @Override
    @Transactional
    public void updateMana(GridInfo gridInfo) {
        this.updateNotNull(gridInfo);
    }

}
